package com.tj.collection.controller.lending;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.tj.collection.bean.ApiResponse;
import com.tj.collection.bean.ModuleResponse;
import com.tj.collection.common.RequestLocalInfo;
import com.tj.collection.controller.lending.request.ClCallQueryRequest;
import com.tj.collection.controller.lending.request.ClCommentRequest;
import com.tj.collection.controller.lending.request.ClExtensionAddRequest;
import com.tj.collection.controller.lending.request.RecordingUploadRequest;
import com.tj.collection.controller.lending.response.*;
import com.tj.collection.db.admin.dao.AdminDAO;
import com.tj.collection.db.dao.*;
import com.tj.collection.db.domain.Admin;
import com.tj.collection.db.domain.Role;
import com.tj.collection.db.entity.*;
import com.tj.collection.db.entity.business.ClCallInfoEntity;
import com.tj.collection.db.enums.RoleKeyEnum;
import com.tj.collection.db.service.AdminRoleService;
import com.tj.collection.enums.*;
import com.tj.collection.service.AllocationService;
import com.tj.collection.service.CollectionApplication;
import com.tj.collection.service.PhoneRecordService;
import com.tj.collection.service.dto.ClPhoneRecordDto;
import com.tj.collection.service.param.CommonCollectionOrderParam;
import com.tj.collection.service.request.ClSmsInputVo;
import com.tj.collection.utils.ConfigUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 催收操作 都放这个controller
 * Created with IntelliJ IDEA.
 * User: pavan
 * Date: 2019/9/10
 * Time: 下午9:09
 */
@RestController
@RequestMapping("/collection/v2")
public class ClCommentController {

    private static final Log LOGGER = LogFactory.getLog(ClCommentController.class);

    @Autowired
    private ConfigUtil configUtil;

    @Autowired
    private AllocationService allocationService;

    @Autowired
    private ClCommentDao clCommentDao;

    @Autowired
    private ClReceiverDao clReceiverDao;

    @Autowired
    private ClReceiverDetailDao clReceiverDetailDao;

    @Autowired
    private PhoneRecordService phoneRecordService;

    @Autowired
    private ClPhoneRecordDao clPhoneRecordDao;

    @Autowired
    private ClAllocationDetailDao clAllocationDetailDao;

    @Autowired
    private ClCallDurationDao clCallDurationDao;

    @Autowired
    private AdminRoleService adminRoleService;

    @Autowired
    private ClStageDao clStageDao;

    @Autowired
    private AdminDAO adminDAO;

    @Autowired
    private CollectionApplication collectionApplication;

    /**
     * 催收模块下拉栏相关数据
     *
     * @return
     */
    @RequestMapping("/case/query")
    public ApiResponse<CollectionOrderCommonResponse> getCollectionCaseCommonInfo() {
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        String appClient = RequestLocalInfo.getRequestBasicInfo().getAppClient();

        List<CollectionStatusEnums> collectionStatus = CollectionStatusEnums.getCollectionStatusEnums();
        List<CollectionStatusEnums> callingResults = CollectionStatusEnums.getCollectionCallingResults();
        List<CollectionStatusEnums> relatives = CollectionStatusEnums.getCollectionRelatives();
        List<String> orderFromList = ChannelMappingEnum.orderFrom();
        List<ClActiveStatusEnum> clActiveStatusEnumList = Lists.newArrayList(ClActiveStatusEnum.values());

        List<ClStageEntity> clStageEntities = clStageDao.getStagesByMerchantCode(merchantCode);
        List<CommonCollectionOrderParam> commonStatusParamList = collectionApplication.getCommonStatusParam();
        List<CommonCollectionOrderParam> conclusionParamList = collectionApplication.getConclusionParam();
        List<CommonCollectionOrderParam> deductTypeList = collectionApplication.getDeductTypeList(appClient);

        return new ApiResponse<>(new CollectionOrderCommonResponse(
                collectionStatus, callingResults, relatives, orderFromList, clStageEntities,
                clActiveStatusEnumList, commonStatusParamList, conclusionParamList, deductTypeList
        ));
    }

    /**
     * 催收员配置
     *
     * @return
     */
    @RequestMapping("/agent/config")
    public ApiResponse<CollectionAgentConfigResponse> getCollectionAgentConfig() {
        Integer isAgentManager = this.hasAllCollectPermission();
        return new ApiResponse<>(new CollectionAgentConfigResponse().setIsAgentManager(isAgentManager));
    }

    /**
     * 判断是否是催收主管或者更高级的权限（用来控制展示员工下拉列表）
     *
     * @return
     */
    private Integer hasAllCollectPermission() {
        List<Role> roleList = adminRoleService.getRolesByAdminId(RequestLocalInfo.getCurrentAdmin().getId());
        List<RoleKeyEnum> roleKeyEnumList = RoleKeyEnum.getCollectionAllPermissionEnum();
        for (RoleKeyEnum roleKeyEnum : roleKeyEnumList) {
            for (Role role : roleList) {
                if (roleKeyEnum.getType().equals(role.getRoleKey())) {
                    return 1;
                }
            }
        }
        return 0;
    }

    /**
     * 备注列表
     *
     * @param clCommentRequest
     * @return
     */
    @RequestMapping("/commentGet/list")
    public ApiResponse collectionCommentGet(@RequestBody ClCommentRequest clCommentRequest) {
        ClReceiverEntity clReceiverEntity = null;
        if (StringUtils.isNotEmpty(clCommentRequest.getCollectionNo())) {
            clReceiverEntity = clReceiverDao.selectByCollectionNo(clCommentRequest.getCollectionNo());
        } else {
            clReceiverEntity = clReceiverDao.selectLastByOrderNo(clCommentRequest.getTradeNo());
        }
        ClReceiverDetailEntity clReceiverDetailEntity = clReceiverDetailDao.selectOneByCollectionNo(clReceiverEntity.getCollectionNo());
        List<ClSmsInputVo> smsList = new ArrayList<>();
        if (StringUtils.isNotEmpty(clReceiverDetailEntity.getSmsUrl())) {
            try {
                String body = HttpUtil.getPage(clReceiverDetailEntity.getSmsUrl());
                JSONObject jsonObject = JSON.parseObject(body);
                smsList = JSON.parseArray(jsonObject.getJSONArray("smsList").toJSONString(), ClSmsInputVo.class);
            } catch (Exception e) {
            }
        }

        List<ClCommentEntity> clCommentEntityList = clCommentDao.selectCommonByCollectionNo(clReceiverEntity.getCollectionNo());
        List<ClPhoneRecordEntity> clPhoneRecordEntityList = clPhoneRecordDao.selectCommonByCollectionNo(clReceiverEntity.getCollectionNo());
        return new ApiResponse<>(new ClCommentResponse(clCommentEntityList, clPhoneRecordEntityList, smsList));
    }

    /**
     * 打标签
     *
     * @param clCommentRequest
     * @return
     */
    @RequestMapping("/comment/add")
    public ApiResponse addCollectionComment(@RequestBody ClCommentRequest clCommentRequest) {
        if (StringUtils.isEmpty(clCommentRequest.getCollectionNo())) {
            return new ApiResponse<>("请先选择账单");
        }
        String productCode = RequestLocalInfo.getCurrentAdmin().getProductCategory();
        String appClient = RequestLocalInfo.getRequestBasicInfo().getAppClient();
        Integer versionCode = RequestLocalInfo.getRequestBasicInfo().getVersionCode();

        Integer adminId = RequestLocalInfo.getCurrentAdmin().getId().intValue();
        String name = RequestLocalInfo.getCurrentAdmin().getName();

        //以当前登录人为准
        clCommentRequest.setFollowId(adminId);
        clCommentRequest.setFollowUp(name);

        String collectionNo = clCommentRequest.getCollectionNo();

        this.contact(
                clCommentRequest.getCollectionNo(),
                clCommentRequest.getFollowId(),
                clCommentRequest.getFollowUp(),
                clCommentRequest.getName(),
                clCommentRequest.getMobile(),
                clCommentRequest.getRelation(),
                clCommentRequest.getContent(),
                clCommentRequest.getCallingResult(),
                clCommentRequest.getType(),
                StringUtils.isEmpty(clCommentRequest.getNextTime()) ?
                        null : DateUtil.getDate(clCommentRequest.getNextTime(), "yyyy-MM-dd HH:mm:ss"),
                appClient
        );
        ClReceiverEntity receiverEntity = clReceiverDao.selectByCollectionNo(collectionNo);
        receiverEntity.setCommentType(clCommentRequest.getType());
        clReceiverDao.updateByPrimaryKey(receiverEntity);

        if (configUtil.getClCommentAddCallRecords()) {
            if (CollectionUtils.isNotEmpty(clCommentRequest.getCallRecords())) {
                List<ClCallDurationEntity> callRecords = clCommentRequest.getCallRecords().stream().map(
                        item -> {
                            ClCallDurationEntity entity = new ClCallDurationEntity();
                            entity.setMobile(item.getMobile())
                                    .setStartTime(item.getStartTime())
                                    .setEndTime(item.getEndTime())
                                    .setCallDuration(item.getCallDuration());
                            return entity;
                        }
                ).collect(Collectors.toList());
                phoneRecordService.addCallDuration(collectionNo,
                        clCommentRequest.getFollowId(),
                        clCommentRequest.getFollowUp(),
                        callRecords);
            } else {
                if (!"web".equals(appClient)) {
                    LOGGER.warn("催收本人标签未传通话记录列表,clCommentRequest:{}", JSON.toJSONString(clCommentRequest));
                }
            }
        }

        //设置活跃状态为失效
        allocationService.invalidateActive(collectionNo);

        if ("android".equals(appClient) && versionCode != null) {
            adminDAO.updateVersionCode(adminId, versionCode);
        }


        ApiResponse apiResponse = null;
        if (clCommentRequest.getSendRepaymentLink() != null && clCommentRequest.getSendRepaymentLink() == 1) {
            try {
                //发送还款链接
                //TODO
            } catch (Exception e) {
                LOGGER.error("催记发送还款链接失败,clCommentRequest:{}", JSON.toJSONString(clCommentRequest), e);
            }
        }
        if (StringUtils.isNotEmpty(clCommentRequest.getDeductType()) && DeductTypeEnum.getEnum(clCommentRequest.getDeductType()) != null) {
            //TODO 抵扣
        }

        return apiResponse != null ? apiResponse : new ApiResponse<>();
    }

    /**
     * 催收打标签
     *
     * @param collectionNo
     * @param adminId
     * @param agentName
     * @param name
     * @param mobile
     * @param relation
     * @param content
     * @param result
     * @param type
     * @param nextTime
     * @param deviceType
     */
    private void contact(String collectionNo, Integer adminId, String agentName, String name, String mobile,
                         String relation, String content, String result, Integer type, Date nextTime,
                         String deviceType) {
        ClReceiverEntity receiverEntity = clReceiverDao.selectByCollectionNo(collectionNo);
        ClAllocationDetailEntity clAllocationDetailEntity = clAllocationDetailDao.getCurrentAllocationByCollectionNo(receiverEntity.getCollectionNo());
        clAllocationDetailEntity.setLastHandleTime(new Date());
        clAllocationDetailEntity.setNextTime(nextTime);
        clAllocationDetailDao.updateByPrimaryKey(clAllocationDetailEntity);

        ClCommentEntity commentEntity = new ClCommentEntity()
                .setAllocationNo(clAllocationDetailEntity.getAllocationNo())
                .setCollectionNo(clAllocationDetailEntity.getCollectionNo())
                .setName(name)
                .setMobile(mobile)
                .setRelation(relation)
                .setFollowId(adminId)
                .setFollowUp(agentName)
                .setContent(content)
                .setDeviceType(deviceType)
                .setCallingResult(result)
                .setType(type)
                .setPromisePayDate(nextTime)
                .setTradeNo(receiverEntity.getOrderNo());
        clCommentDao.insert(commentEntity);
    }

    /**
     * 增加催记
     *
     * @param clCommentRequest
     * @return
     */
    @RequestMapping("/phone/record/add")
    public ApiResponse addPhoneRecord(@RequestBody ClCommentRequest clCommentRequest) {
        if (StringUtils.isEmpty(clCommentRequest.getCollectionNo())) {
            return new ApiResponse<>("请先选择账单");
        }
        String appClient = RequestLocalInfo.getRequestBasicInfo().getAppClient();
        //以当前登录人为准
        clCommentRequest.setFollowId(RequestLocalInfo.getCurrentAdmin().getId().intValue())
                .setFollowUp(RequestLocalInfo.getCurrentAdmin().getName());

        Date nextTime = StringUtils.isEmpty(clCommentRequest.getNextTime()) ?
                null : DateUtil.getDate(clCommentRequest.getNextTime(), "yyyy-MM-dd HH:mm:ss");

        ClPhoneRecordDto clPhoneRecordDto = new ClPhoneRecordDto();
        clPhoneRecordDto.setCollectionNo(clCommentRequest.getCollectionNo())
                .setName(clCommentRequest.getName())
                .setMobile(clCommentRequest.getMobile())
                .setFollowId(clCommentRequest.getFollowId())
                .setFollowUp(clCommentRequest.getFollowUp())
                .setCallingResult(clCommentRequest.getCallingResult())
                .setRelation(clCommentRequest.getRelation())
                .setContent(clCommentRequest.getContent())
                .setDeviceType(appClient)
                .setPromisePayDate(nextTime);

        phoneRecordService.addRecord(clPhoneRecordDto);

        if (configUtil.getClCommentAddCallRecords()) {
            if (CollectionUtils.isNotEmpty(clCommentRequest.getCallRecords())) {
                List<ClCallDurationEntity> callRecords = clCommentRequest.getCallRecords().stream().map(
                        item -> {
                            ClCallDurationEntity entity = new ClCallDurationEntity();
                            entity.setMobile(item.getMobile())
                                    .setStartTime(item.getStartTime())
                                    .setEndTime(item.getEndTime())
                                    .setCallDuration(item.getCallDuration());
                            return entity;
                        }
                ).collect(Collectors.toList());
                phoneRecordService.addCallDuration(clPhoneRecordDto.getCollectionNo(),
                        clCommentRequest.getFollowId(),
                        clCommentRequest.getFollowUp(),
                        callRecords);
            } else {
                if (!"web".equals(appClient)) {
                    LOGGER.warn("催收其他人标签未传通话记录列表,clCommentRequest:{}", JSON.toJSONString(clCommentRequest));
                }
            }
        }
        return new ApiResponse<>();
    }


    /**
     * 催收列表
     *
     * @param clCallQueryRequest
     * @return
     */
    @RequestMapping("/recording/list")
    public ModuleResponse collectionRecordingList(@RequestBody ClCallQueryRequest clCallQueryRequest, Page page) {
        Map<String, Object> params = JSON.parseObject(JSON.toJSONString(clCallQueryRequest), HashMap.class);
        if (StringUtils.isNotEmpty(clCallQueryRequest.getStartDate()) && StringUtils.isNotEmpty(clCallQueryRequest.getEndDate())) {
            params.put("gmtStartTime", DateUtil.getDate(clCallQueryRequest.getStartDate(), "yyyy-MM-dd"));
            params.put("gmtEndTime", DateUtil.addDate(DateUtil.getDate(clCallQueryRequest.getEndDate(), "yyyy-MM-dd"), 1));
        }
        params.put("page", page);
        List<ClCallDurationEntity> clCallDurationEntityList = clCallDurationDao.selectCallDurationByParams(params);
        return new ModuleResponse<>(new ClCallDurationResponse(clCallDurationEntityList), page);
    }

    /**
     * 催收录音文件上传
     *
     * @param recordingUploadRequest
     * @return
     */
    @ParamsValidate
    @RequestMapping("/recording/upload")
    public ApiResponse recordingUpload(@RequestBody RecordingUploadRequest recordingUploadRequest) {
        Admin admin = RequestLocalInfo.getCurrentAdmin();
        ClCallDurationEntity clCallDurationEntity = new ClCallDurationEntity();
        clCallDurationEntity.setCollectionNo(recordingUploadRequest.getCollectionNo());
        clCallDurationEntity.setFollowId(admin.getId().intValue());
        clCallDurationEntity.setFollowUp(admin.getName());
        clCallDurationEntity.setMobile(recordingUploadRequest.getMobile());
        clCallDurationEntity.setStartTime(recordingUploadRequest.getStartTime());
        clCallDurationEntity.setEndTime(recordingUploadRequest.getEndTime());
        clCallDurationEntity.setCallDuration(recordingUploadRequest.getCallDuration());
        clCallDurationEntity.setVideoUrl(recordingUploadRequest.getUrl());
        phoneRecordService.addCallDurationV2(recordingUploadRequest.getCollectionNo(), clCallDurationEntity);
        LOGGER.info("录音文件上传成功,request:{},adminId:{}", JSON.toJSONString(recordingUploadRequest), admin.getId());
        return new ApiResponse<>();
    }

    /**
     * 催收展期申请
     *
     * @param clExtensionAddRequest
     * @return
     */
    @ParamsValidate
    @RequestMapping("/extension/submit")
    public ApiResponse submitExtensionApplication(@RequestBody ClExtensionAddRequest clExtensionAddRequest) {
        Admin admin = RequestLocalInfo.getCurrentAdmin();
        ClReceiverEntity clReceiverEntity = clReceiverDao.selectByCollectionNo(clExtensionAddRequest.getCollectionNo());
        if (!ReceiverStatusEnum.ALLOCATE_SUCCESS.getStatus().equals(clReceiverEntity.getStatus())) {
            throw new ApplicationException("Order status does not match");
        }
        clReceiverEntity.setExtensionStatus(ExtensionStatusEnum.WAITING_EXTENSION_REPAY.getStatus());
        clReceiverDao.updateByPrimaryKey(clReceiverEntity);
        LOGGER.info("催收展期申请成功,request:{},adminId:{}", JSON.toJSONString(clExtensionAddRequest), admin.getId());
        return new ApiResponse<>();
    }

    /**
     * 催记及通话记录列表
     *
     * @param clCallQueryRequest
     * @param page
     * @return
     */
    @RequestMapping("/callDuration/list")
    public ModuleResponse getCallDuration(@RequestBody ClCallQueryRequest clCallQueryRequest, Page page) {
        List<ClCallInfoEntity> clCallInfoEntityList = clCallDurationDao.selectCallDurationInfoList(getCallDurationParams(clCallQueryRequest), page);
        return new ModuleResponse<>(new ClCallDurationInfoResponse(clCallInfoEntityList), page);
    }

    /**
     * 催记及通话记录列表
     *
     * @param clCallQueryRequest
     * @param page
     * @return
     */
    @RequestMapping("/callDuration/list/export")
    public ModuleResponse getCallDurationExport(@RequestBody ClCallQueryRequest clCallQueryRequest, Page page) {
        List<ClCallInfoEntity> clCallInfoEntityList = clCallDurationDao.selectCallDurationInfoList(getCallDurationParams(clCallQueryRequest), page);
        return new ModuleResponse<>(new ClCallDurationInfoResponse(clCallInfoEntityList, true), page);
    }

    private Map<String, Object> getCallDurationParams(ClCallQueryRequest clCallQueryRequest) {
        String merchantCode = RequestLocalInfo.getCurrentAdmin().getMerchantCode();
        Map<String, Object> params = new HashMap<>();
        params.put("merchantCode", merchantCode);
        params.put("orderNo", clCallQueryRequest.getTradeNo());
        params.put("followId", clCallQueryRequest.getFollowId());
        params.put("mobile", clCallQueryRequest.getMobile());
        if (StringUtils.isNotEmpty(clCallQueryRequest.getStartDate()) && StringUtils.isNotEmpty(clCallQueryRequest.getEndDate())) {
            params.put("gmtStartTime", DateUtil.getDate(clCallQueryRequest.getStartDate(), "yyyy-MM-dd"));
            params.put("gmtEndTime", DateUtil.addDate(DateUtil.getDate(clCallQueryRequest.getEndDate(), "yyyy-MM-dd"), 1));
        }
        return params;
    }

}
